﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Windows.Forms;

namespace Øving3Blackjack
{
    class Controller
    {
        private const int STARTGOLD = 5000;
        private const int STARTBET = 5;
        private const int MINBET = 5;
        private const int MAXBET = 500;

        private Form1 form1;
        private Deck deck;
        private CardsInPlay cardsInPlay;
        private Boolean isInitializing = true;
        private int bet;
        private int insuranceBet;
        private int gold;

        private Boolean split1 = false;
        private Boolean split2 = false;

        public Controller(Form1 form1)
        {
            this.form1 = form1;
            deck = new Deck(1);
            cardsInPlay = new CardsInPlay();
        }

        public void changeBet(int amount)
        {
            if ((bet + amount) > 500)
            {
                bet = 500;
            }
            else if ((bet + amount) < 5)
            {
                bet = 5;
            }
            else if ((bet + amount) > gold)
            {
                bet = gold;
            }
            else
            {
                bet += amount;
            }
            form1.changeLabelBet("Bet: " + bet);
        }


        public void start()
        {
            form1.disableActions();
            form1.changeLabelGold("Your gold: " + STARTGOLD);
            form1.changeLabelBet("Bet: " + STARTBET);
            form1.changeLabelBetMin("Maximum bet: " + MAXBET);
            form1.changeLabelBetMax("Minimum bet: " + MINBET);
            bet = STARTBET;
            gold = STARTGOLD;
        }

        public void newGame()
        {
            form1.changeLabelResult("");
            form1.changeLabelOutput("");

            form1.changeLabelGold("Your gold: " + STARTGOLD);
            form1.changeLabelBet("Bet: " + STARTBET);
            form1.changeLabelBetMin("Maximum bet: " + MAXBET);
            form1.changeLabelBetMax("Minimum bet: " + MINBET);
            
            bet = STARTBET;
            gold = STARTGOLD;

            form1.updatePanelImage();
            form1.disableBets();

            isInitializing = true;
            deck.shuffleDeck();
            cardsInPlay.emptyHands();

            form1.enableBets();
            form1.disableActions();
            form1.changeButtonPlay(true);
        }
        public void changeDecks(int decks)
        {
            deck.changeDecks(decks);
        }

        public void play()
        {
            form1.changeButtonPlay(false);
            cardsInPlay.PlayerDone = false;
            cardsInPlay.PlayerSplit = false;
            cardsInPlay.emptyHands();
            insuranceBet = 0;
            form1.updatePanelImage();
            form1.disableActions();
            form1.disableBets();
            if (bet > 500)
            {
                bet = 500;
            }

            if (bet > gold)
            {
                bet = gold;
            }

            if (gold < 5)
            {
                form1.changeLabelResult("No more gold, YOU LOSE!");
                form1.changeButtonPlay(false);
                return;
            }

            if (deck.hasFewCards())
            {
                deck.shuffleDeck();
                form1.changeLabelOutput("Stokker kortene.");
            }
            
            gold -= bet;
            form1.changeLabelBet("Bet: " + bet);
            form1.changeLabelGold("Your gold: " + gold);
            
            cardsInPlay.addPlayerCard(deck.getRemoveCard());
            cardsInPlay.calcNewPlayerValue();
            cardsInPlay.addDealerCard(deck.getRemoveCard());
            cardsInPlay.calcNewDealerValue();
            cardsInPlay.addPlayerCard(deck.getRemoveCard());
            cardsInPlay.calcNewPlayerValue();
            cardsInPlay.addDealerCard(deck.getRemoveCard());
            cardsInPlay.calcNewDealerValue();
            
            form1.updatePanelImage();

            if (cardsInPlay.dealerHasAce())
            {
                form1.openInsuranceQuery();
            }

            if (cardsInPlay.getPlayerValue() == 21)
            {
                form1.disableActions();
                this.dealerTurn();
            }
            else
            {
                form1.changeLabelResult("Du har " + cardsInPlay.getPlayerValue());
                form1.changeButtonHit(true);
                form1.changeButtonStand(true);
                form1.changeButtonSurrender(true);

                if (gold > bet)
                {
                    form1.changeButtonDoubleDown(true);
                }
                if (cardsInPlay.playerCanSplit())
                {
                    form1.changeButtonSplit(true);
                }
            }
        }
        public void hit()
        {
            form1.disableActions();
            if (!cardsInPlay.PlayerSplit)
            {
                cardsInPlay.addPlayerCard(deck.getRemoveCard());
                cardsInPlay.calcNewPlayerValue();
                form1.updatePanelImage();
                form1.changeLabelResult("Du har " + cardsInPlay.getPlayerValue());

                   if (cardsInPlay.getPlayerValue() >= 21)
                   {
                       this.dealerTurn();
                   }
                   else
                   {
                      form1.changeButtonHit(true);
                      form1.changeButtonStand(true);
                   }
            }
            else
            {
                if (!split1)
                {
                    cardsInPlay.addPlayerCard(deck.getRemoveCard());
                    cardsInPlay.calcNewPlayerValue();
                    form1.updatePanelImage();
                    form1.changeLabelResult("Du har " + cardsInPlay.getPlayerValue() + "\nDu har " + cardsInPlay.getSplitValue());
                    if (cardsInPlay.getPlayerValue() >= 21)
                    {
                        split1 = true;
                        if (split2)
                        {
                            this.dealerTurn();
                        }
                        else
                        {
                            form1.changeButtonHit(true);
                            form1.changeButtonStand(true);
                        }
                    }
                    else
                    {
                        form1.changeButtonHit(true);
                        form1.changeButtonStand(true);
                    }
                }
                else
                {
                    cardsInPlay.addSplitCard(deck.getRemoveCard());
                    cardsInPlay.calcNewSplitValue();
                    form1.updatePanelImage();
                    form1.changeLabelResult("Du har " + cardsInPlay.getPlayerValue() + "\nDu har " + cardsInPlay.getSplitValue());
                    if (cardsInPlay.getSplitValue() >= 21)
                    {
                        this.dealerTurn();
                    }
                    else
                    {
                        form1.changeButtonHit(true);
                        form1.changeButtonStand(true);
                    }
                }
            }
        }
        public void stand()
        {
            form1.disableActions();
            if (!cardsInPlay.PlayerSplit)
            {
                this.dealerTurn();
            }
            else
            {
                if (!split1 && !split2)
                {
                    split1 = true;
                    form1.changeButtonHit(true);
                    form1.changeButtonStand(true);
                }
                else if (!split1)
                {
                    split1 = true;
                    this.dealerTurn();
                }
                else 
                {
                    split2 = true;
                    this.dealerTurn();
                }
            }
        }
        public void doubleDown()
        {
            form1.disableActions();
            gold -= bet;
            bet = bet * 2;
            form1.changeLabelBet("Bet: " + bet);
            form1.changeLabelGold("Your gold: " + gold);
            cardsInPlay.addPlayerCard(deck.getRemoveCard());
            cardsInPlay.calcNewPlayerValue();
            form1.updatePanelImage();
            form1.changeLabelResult("Du har " + cardsInPlay.getPlayerValue());
            this.dealerTurn();
        }
        public void split()
        {
            form1.disableActions();
            cardsInPlay.PlayerSplit = true;
            gold -= bet;
            form1.changeLabelGold("Your gold: " + gold);

            cardsInPlay.split();
            cardsInPlay.calcNewPlayerValue();
            cardsInPlay.calcNewSplitValue();
            cardsInPlay.addPlayerCard(deck.getRemoveCard());
            cardsInPlay.calcNewPlayerValue();
            cardsInPlay.addSplitCard(deck.getRemoveCard());
            cardsInPlay.calcNewSplitValue();

            form1.updatePanelImage();
            
            
            if (cardsInPlay.getPlayerValue() == 21)
            {
                split1 = true;
                form1.changeLabelResult("Du har 21 på første hånden, og står automatisk." +
                    "\nDu har " + cardsInPlay.getSplitValue());
            }
            if (cardsInPlay.getSplitValue() == 21)
            {
                form1.changeLabelResult("Du har " + cardsInPlay.getSplitValue() +
                    "\nDu har 21 på andre hånden, og står automatisk.");
            }

            if (split1 && split2)
            {
                form1.changeLabelResult("Du har 21 på begge hendene og står automatisk.");
                System.Threading.Thread.Sleep(1000);
                dealerTurn();
            }
            else
            {
                form1.changeLabelResult("Du har " + cardsInPlay.getPlayerValue() + "\nDu har " + cardsInPlay.getSplitValue());
                form1.changeButtonHit(true);
                form1.changeButtonStand(true);
            }
        }
        public void surrender()
        {
            cardsInPlay.PlayerDone = true;
            form1.updatePanelImage();
            form1.changeLabelResult("Du gir opp hånden.");
            gold += (bet / 2);
            form1.changeLabelGold("Your gold: " + gold);
            form1.changeLabelOutput("");
            form1.enableBets();
            form1.changeButtonPlay(true);
        }
        public void insurance()
        {
            insuranceBet = (bet / 2);
            gold -= insuranceBet;
            form1.changeLabelGold("Your gold: " + gold);
        }

        public void paintCards(object sender, PaintEventArgs e)
        {
            if (isInitializing)
            {
                isInitializing = false;
            }
            else
            {
                cardsInPlay.paintAllCards(sender, e);
            }   
        }

        private void dealerTurn()
        {
            cardsInPlay.PlayerDone = true;
            form1.updatePanelImage();
            if (!cardsInPlay.PlayerSplit)
            {
                if (cardsInPlay.getPlayerValue() > 21)
                {
                    if (cardsInPlay.dealerHasBJ() && insuranceBet > 0)
                    {
                        form1.changeLabelResult("Du fikk " + cardsInPlay.getPlayerValue() + ". Du taper runden, men vinner på insurance!");
                        gold += insuranceBet * 2;
                        form1.changeLabelGold("Your gold: " + gold);
                    }
                    form1.changeLabelResult("Du fikk " + cardsInPlay.getPlayerValue() + ". Du taper!");
                }
                else if (cardsInPlay.dealerHasBJ())
                {
                    if (insuranceBet > 0)
                    {
                        form1.changeLabelResult("Dealer har Blackjack.\nDu taper runden, men vinner på insurance!");
                        gold += insuranceBet * 2;
                        form1.changeLabelGold("Your gold: " + gold);
                    }
                    else
                    {
                        form1.changeLabelResult("Dealer har Blackjack. Du taper!");
                    }
                }
                else if (cardsInPlay.playerHasBJ())
                {
                    form1.changeLabelResult("Du har Blackjack. Du vinner!");
                    gold += bet + ((bet * 3) / 2);
                }
                else
                {
                    while (cardsInPlay.getDealerValue() < 17)
                    {
                        cardsInPlay.addDealerCard(deck.getRemoveCard());
                        cardsInPlay.calcNewDealerValue();
                        form1.updatePanelImage();
                    }
                    if (cardsInPlay.getDealerValue() > 21)
                    {
                        form1.changeLabelResult("Du fikk " + cardsInPlay.getPlayerValue() + ". Dealer bustet med " + cardsInPlay.getDealerValue() + ". Du vinner!");
                        gold += 2 * bet;
                    }
                    else if (cardsInPlay.getDealerValue() < cardsInPlay.getPlayerValue())
                    {
                        form1.changeLabelResult("Du fikk " + cardsInPlay.getPlayerValue() + ". Dealer fikk " + cardsInPlay.getDealerValue() + ". Du vinner!");
                        gold += 2 * bet;
                    }
                    else if (cardsInPlay.getDealerValue() == cardsInPlay.getPlayerValue())
                    {
                        form1.changeLabelResult("Både du og Dealer fikk " + cardsInPlay.getPlayerValue() + ". Du taper!");
                    }
                    else
                    {
                        form1.changeLabelResult("Du fikk " + cardsInPlay.getPlayerValue() + ". Dealer fikk " + cardsInPlay.getDealerValue() + ". Du taper!");
                    }
                }
            }
            else
            {
                if (cardsInPlay.dealerHasBJ())
                {
                    if (insuranceBet > 0)
                    {
                        form1.changeLabelResult("Dealer har Blackjack.\nDu taper runden, men vinner på insurance!");
                        gold += insuranceBet * 4;
                        form1.changeLabelGold("Your gold: " + gold);
                    }
                    else
                    {
                        form1.changeLabelResult("Dealer har Blackjack. Du taper!");
                    }
                }
                else
                {
                    Boolean split1Bust = false;
                    Boolean split2Bust = false;
                    if (cardsInPlay.getPlayerValue() > 21) 
                    {
                        split1Bust = true;
                    }
                    if (cardsInPlay.getSplitValue() > 21)
                    {
                        split2Bust = true;
                    }

                    if (split1Bust && split2Bust)
                    {
                        form1.changeLabelResult("Du fikk " + cardsInPlay.getPlayerValue() + "\nDu fikk " + cardsInPlay.getSplitValue() + ". Du taper på begge hendene!");
                    }
                    else
                    {
                        while (cardsInPlay.getDealerValue() < 17)
                        {
                            cardsInPlay.addDealerCard(deck.getRemoveCard());
                            cardsInPlay.calcNewDealerValue();
                            form1.updatePanelImage();
                        }
                        if (cardsInPlay.getDealerValue() > 21)
                        {
                            if (split1Bust || split2Bust)
                            {
                                form1.changeLabelResult("Du fikk " + cardsInPlay.getPlayerValue() + "\nDu fikk " + cardsInPlay.getSplitValue() + ". Dealer fikk " + cardsInPlay.getDealerValue() + ". Du vinner på én hånd!");
                                gold += bet * 2;
                            }
                            else
                            {
                                form1.changeLabelResult("Du fikk " + cardsInPlay.getPlayerValue() + "\nDu fikk " + cardsInPlay.getSplitValue() + ". Dealer fikk " + cardsInPlay.getDealerValue() + ". Du vinner på begge hendene!");
                                gold += bet * 4;
                            }
                        }
                        else 
                        {
                            Boolean dealerWins1 = false;
                            Boolean dealerWins2 = false;
                            if (cardsInPlay.getDealerValue() >= cardsInPlay.getPlayerValue() || split1Bust)
                            {
                                dealerWins1 = true;
                            }
                            if (cardsInPlay.getDealerValue() >= cardsInPlay.getSplitValue() || split2Bust)
                            {
                                dealerWins2 = true;
                            }

                            if (dealerWins1 && dealerWins2)
                            {
                                form1.changeLabelResult("Du fikk " + cardsInPlay.getPlayerValue() + "\nDu fikk " + cardsInPlay.getSplitValue() + ". Dealer fikk " + cardsInPlay.getDealerValue() + ". Du taper på begge hendene!");
                            }
                            else if (dealerWins1 || dealerWins2)
                            {
                                form1.changeLabelResult("Du fikk " + cardsInPlay.getPlayerValue() + "\nDu fikk " + cardsInPlay.getSplitValue() + ". Dealer fikk " + cardsInPlay.getDealerValue() + ". Du vinner på én hånd!");
                                gold += bet * 2;
                            }
                            else
                            {
                                form1.changeLabelResult("Du fikk " + cardsInPlay.getPlayerValue() + "\nDu fikk " + cardsInPlay.getSplitValue() + ". Dealer fikk " + cardsInPlay.getDealerValue() + ". Du vinner på begge hendene!");
                                gold += bet * 4;
                            }
                        }
                    }
                }
            }
            form1.changeLabelGold("Your gold: " + gold);
            form1.changeLabelOutput("");
            form1.enableBets();
            form1.changeButtonPlay(true);

        }

    }
}